using Serilog;
using Serilog.Events;
using Serilog.Sinks.Grafana.Loki;
using Serilog.Formatting.Compact;
using System.Diagnostics;
using Serilog.Core;

namespace WeatherSystem.API.Configurations
{
    /// <summary>
    /// 结构化日志配置
    /// </summary>
    public static class LoggingConfiguration
    {
        public static void ConfigureSerilog(this WebApplicationBuilder builder)
        {
            var lokiUrl = Environment.GetEnvironmentVariable("LOKI_URL") ?? "http://localhost:3100";
            
            // 配置Serilog
            var loggerConfig = new LoggerConfiguration()
                .MinimumLevel.Information()
                .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                .MinimumLevel.Override("System", LogEventLevel.Warning)
                .MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Information)
                .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .Enrich.WithProperty("Application", "WeatherSystem")
                .Enrich.WithProperty("Service", "weather-api")
                .Enrich.WithProperty("Version", GetApplicationVersion())
                .Enrich.WithProperty("Environment", builder.Environment.EnvironmentName)
                .Enrich.WithProperty("MachineName", Environment.MachineName)
                .WriteTo.Console(new CompactJsonFormatter())
                .WriteTo.File(
                    formatter: new CompactJsonFormatter(),
                    path: Path.Combine("logs", "weather-system-.log"),
                    rollingInterval: RollingInterval.Day,
                    retainedFileCountLimit: 7,
                    fileSizeLimitBytes: 100 * 1024 * 1024, // 100MB
                    rollOnFileSizeLimit: true);

            // Loki集成 (生产环境)
            if (builder.Environment.IsProduction() || 
                Environment.GetEnvironmentVariable("ENABLE_LOKI_LOGGING") == "true")
            {
                loggerConfig.WriteTo.GrafanaLoki(
                    uri: lokiUrl,
                    labels: new List<LokiLabel>
                    {
                        new() { Key = "service", Value = "weather-api" },
                        new() { Key = "environment", Value = builder.Environment.EnvironmentName },
                        new() { Key = "application", Value = "WeatherSystem" }
                    },
                    textFormatter: new CompactJsonFormatter(),
                    batchPostingLimit: 1000,
                    queueLimit: 100000,
                    period: TimeSpan.FromSeconds(10));
            }

            // 错误日志单独文件
            if (builder.Environment.IsProduction())
            {
                loggerConfig.WriteTo.File(
                    formatter: new CompactJsonFormatter(),
                    path: Path.Combine("logs", "weather-system-errors-.log"),
                    restrictedToMinimumLevel: LogEventLevel.Error,
                    rollingInterval: RollingInterval.Day,
                    retainedFileCountLimit: 90);
            }

            Log.Logger = loggerConfig.CreateLogger();

            builder.Host.UseSerilog();
        }

        public static void AddStructuredLogging(this IServiceCollection services, IConfiguration configuration)
        {
            // 添加性能计数器
            services.AddSingleton<ActivitySource>(provider =>
                new ActivitySource("WeatherSystem.API"));

            // 添加自定义日志丰富器
            services.AddSingleton<ILogEventEnricher, UserContextEnricher>();
            services.AddSingleton<ILogEventEnricher, RequestContextEnricher>();

            // 配置日志过滤器
            services.Configure<LoggerFilterOptions>(options =>
            {
                // 过滤敏感信息
                options.Rules.Add(new LoggerFilterRule(
                    "Microsoft.EntityFrameworkCore.Database.Command",
                    "Microsoft.EntityFrameworkCore.Database.Command",
                    LogLevel.Information,
                    (providerName, categoryName, logLevel) => false));
            });
        }

        private static string GetApplicationVersion()
        {
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            var version = assembly.GetName().Version;
            return version?.ToString() ?? "1.0.0";
        }
    }

    /// <summary>
    /// 用户上下文日志丰富器
    /// </summary>
    public class UserContextEnricher : ILogEventEnricher
    {
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            // 这里可以添加用户上下文信息，如用户ID、角色等
            // 需要从HttpContext获取
        }
    }

    /// <summary>
    /// 请求上下文日志丰富器
    /// </summary>
    public class RequestContextEnricher : ILogEventEnricher
    {
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            // 添加请求ID、IP地址等信息
            if (Activity.Current != null)
            {
                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("TraceId", Activity.Current.TraceId));
                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("SpanId", Activity.Current.SpanId));
            }
        }
    }
}